///*
// * test.c
// *
// * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
// * Copyright (C) 2009-2012 Tomi Valkeinen
//
// * This program is free software; you can redistribute it and/or modify it
// * under the terms of the GNU General Public License version 2 as published by
// * the Free Software Foundation.
// *
// * This program is distributed in the hope that it will be useful, but WITHOUT
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
// * more details.
// *
// * You should have received a copy of the GNU General Public License along with
// * this program.  If not, see <http://www.gnu.org/licenses/>.
// */
//
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//#include <errno.h>
//#include <fcntl.h>
//#include <unistd.h>
//#include <getopt.h>
//#include <time.h>
//
//#include <sys/ioctl.h>
//#include <sys/stat.h>
//#include <sys/mman.h>
//
//#include <linux/fb.h>
//
//#include "common.h"
//
//static struct fb_info fb_info;
//
//static void draw_pixel(struct fb_info *fb_info, int x, int y, unsigned color)
//{
//	void *fbmem;
//
//	fbmem = fb_info->ptr;
//	if (fb_info->var.bits_per_pixel == 8) {
//		unsigned char *p;
//
//		fbmem += fb_info->fix.line_length * y;
//
//		p = fbmem;
//
//		p += x;
//
//		*p = color;
//	} else if (fb_info->var.bits_per_pixel == 16) {
//		unsigned short c;
//		unsigned r = (color >> 16) & 0xff;
//		unsigned g = (color >> 8) & 0xff;
//		unsigned b = (color >> 0) & 0xff;
//		unsigned short *p;
//
//		r = r * 32 / 256;
//		g = g * 64 / 256;
//		b = b * 32 / 256;
//
//		c = (r << 11) | (g << 5) | (b << 0);
//
//		fbmem += fb_info->fix.line_length * y;
//
//		p = fbmem;
//
//		p += x;
//
//		*p = c;
//	} else if (fb_info->var.bits_per_pixel == 24) {
//		 unsigned char *p;
//
//		p = (unsigned char *)fbmem + fb_info->fix.line_length * y + 3 * x;
//		*p++ = color;
//		*p++ = color >> 8;
//		*p = color >> 16;
//	} else {
//		unsigned int *p;
//
//		fbmem += fb_info->fix.line_length * y;
//
//		p = fbmem;
//
//		p += x;
//
//		*p = color;
//	}
//}
//
//static void fill_screen(struct fb_info *fb_info)
//{
//	unsigned x, y;
//	unsigned h = fb_info->var.yres;
//	unsigned w = fb_info->var.xres;
//
//	for (y = 0; y < h; y++) {
//		for (x = 0; x < w; x++) {
//			if (x < 20 && y < 20)
//				draw_pixel(fb_info, x, y, 0xffffff);
//			else if (x < 20 && (y > 20 && y < h - 20))
//				draw_pixel(fb_info, x, y, 0xff);
//			else if (y < 20 && (x > 20 && x < w - 20))
//				draw_pixel(fb_info, x, y, 0xff00);
//			else if (x > w - 20 && (y > 20 && y < h - 20))
//				draw_pixel(fb_info, x, y, 0xff0000);
//			else if (y > h - 20 && (x > 20 && x < w - 20))
//				draw_pixel(fb_info, x, y, 0xffff00);
//			else if (x == 20 || x == w - 20 ||
//					y == 20 || y == h - 20)
//				draw_pixel(fb_info, x, y, 0xffffff);
//			else if (x == y || w - x == h - y)
//				draw_pixel(fb_info, x, y, 0xff00ff);
//			else if (w - x == y || x == h - y)
//				draw_pixel(fb_info, x, y, 0x00ffff);
//			else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) {
//				int t = x * 3 / w;
//				unsigned r = 0, g = 0, b = 0;
//				unsigned c;
//				if (fb_info->var.bits_per_pixel == 16) {
//					if (t == 0)
//						b = (y % 32) * 256 / 32;
//					else if (t == 1)
//						g = (y % 64) * 256 / 64;
//					else if (t == 2)
//						r = (y % 32) * 256 / 32;
//				} else {
//					if (t == 0)
//						b = (y % 256);
//					else if (t == 1)
//						g = (y % 256);
//					else if (t == 2)
//						r = (y % 256);
//				}
//				c = (r << 16) | (g << 8) | (b << 0);
//				draw_pixel(fb_info, x, y, c);
//			} else {
//				draw_pixel(fb_info, x, y, 0);
//			}
//		}
//
//	}
//
//	fb_put_string(fb_info, w / 3 * 2, 30, "RED", 3, 0xffffff, 1, 3);
//	fb_put_string(fb_info, w / 3, 30, "GREEN", 5, 0xffffff, 1, 5);
//	fb_put_string(fb_info, 20, 30, "BLUE", 4, 0xffffff, 1, 4);
//}
//
//void fill_screen_solid(struct fb_info *fb_info, unsigned int color)
//{
//
//	unsigned x, y;
//	unsigned h = fb_info->var.yres;
//	unsigned w = fb_info->var.xres;
//
//	for (y = 0; y < h; y++) {
//		for (x = 0; x < w; x++)
//			draw_pixel(fb_info, x, y, color);
//	}
//}
//
//static void do_fill_screen(struct fb_info *fb_info, int pattern)
//{
//
//	switch (pattern) {
//	case 1:
//		fill_screen_solid(fb_info, 0xff0000);
//		break;
//	case 2:
//		fill_screen_solid(fb_info, 0x00ff00);
//		break;
//	case 3:
//		fill_screen_solid(fb_info, 0x0000ff);
//		break;
//	case 4:
//		fill_screen_solid(fb_info, 0xffffff);
//		break;
//	case 0:
//	default:
//		fill_screen(fb_info);
//		break;
//	}
//}
//
//void show_help(void)
//{
//	printf("Usage: fb-test -f fbnum -r -g -b -w -p pattern\n");
//	printf("Where -f fbnum   = framebuffer device number\n");
//	printf("      -r         = fill framebuffer with red\n");
//	printf("      -g         = fill framebuffer with green\n");
//	printf("      -b         = fill framebuffer with blue\n");
//	printf("      -w         = fill framebuffer with white\n");
//	printf("      -p pattern = fill framebuffer with pattern number\n");
//}
//
//int main(int argc, char **argv)
//{
//	int opt;
//	int req_fb = 0;
//	int req_pattern = 0;
//
//	printf("fb-test %d.%d.%d (%s)\n", VERSION, PATCHLEVEL, SUBLEVEL,
//		VERSION_NAME);
//
//	while ((opt = getopt(argc, argv, "hrgbwp:f:")) != -1) {
//		switch (opt) {
//		case 'f':
//			req_fb = atoi(optarg);
//			break;
//		case 'p':
//			req_pattern = atoi(optarg);
//			break;
//		case 'r':
//			req_pattern = 1;
//			break;
//		case 'g':
//			req_pattern = 2;
//			break;
//		case 'b':
//			req_pattern = 3;
//			break;
//		case 'w':
//			req_pattern = 4;
//			break;
//		case 'h':
//			show_help();
//			return 0;
//		default:
//			exit(EXIT_FAILURE);
//		}
//	}
//
//	fb_open(req_fb, &fb_info);
//
//	do_fill_screen(&fb_info, req_pattern);
//
//	return 0;
//}

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
/*显示屏相关头文件*/
#include <linux/fb.h>
#include <sys/mman.h>

void lcd_show_pixel(unsigned char *fbmem, int line_length, int bpp,
 int x, int y, unsigned int color)
{
 unsigned char *p8 = (unsigned char *)(fbmem + y * line_length + x * bpp / 8);
 unsigned short *p16 = (unsigned short *)p8;
 unsigned int *p32 = (unsigned int *)p8;
 unsigned int red, green, blue;
 switch(bpp)
 {
 case 8:
 {
 *p8 = (unsigned char)(color & 0xf);
 break;
 }
 case 16:
 {
 red = (color >> 16) & 0xff;
 green = (color >> 8) & 0xff;
 blue = (color >> 0) & 0xff;
 *p16 = (unsigned short)(((red >> 3) << 11) | ((green >> 2) <<5) | ((blue >> 3) << 0));
 break;
 }
 case 32:
 {
 *p32 = color;
 break;
 }
 default:
 {
 printf("can not support %d bpp", bpp);
 break;
 }
 }
}
int main()
{
 struct fb_var_screeninfo vinfo;
 struct fb_fix_screeninfo finfo;
 
 unsigned int color;
 unsigned char *fbp = 0;
 int fp = 0;
 int x, y;
 fp = open("/dev/fb0", O_RDWR);
 if (fp < 0)
 {
 printf("Error : Can not open framebuffer device/n");
 exit(1);
 }
 if (ioctl(fp, FBIOGET_FSCREENINFO, &finfo))
 {
 printf("Error reading fixed information/n");
 exit(2);
 }
 if (ioctl(fp, FBIOGET_VSCREENINFO, &vinfo))
 {
 printf("Error reading variable information/n");
 exit(3);
 }
 printf("The mem is :%d\n", finfo.smem_len);
 printf("The line_length is :%d\n", finfo.line_length);
 printf("The xres is :%d\n", vinfo.xres);
 printf("The yres is :%d\n", vinfo.yres);
 printf("bits_per_pixel is :%d\n", vinfo.bits_per_pixel);
 /*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来，得到一个指向这块空间的指针*/
 fbp =(unsigned char *) mmap (0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
 if ((int) fbp == -1)
 {
 printf ("Error: failed to map framebuffer device to memory./n");
 exit (4);
 }
 /*刷红色*/
 color = 0xff << 16;
 for (y = 0; y < vinfo.yres; y++)
 {
 for(x = 0; x < vinfo.xres; x++)
 lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
 }
 usleep(1000*2000);
 /*刷绿色*/
 color = 0xff << 8;
 for (y = 0; y < vinfo.yres; y++)
 {
 for(x = 0; x < vinfo.xres; x++)
 lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
 }
 usleep(1000*2000);
 /*刷蓝色*/
 color = 0xff;
 for (y = 0; y < vinfo.yres; y++)
 {
 for(x = 0; x < vinfo.xres; x++)
 lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
 }
 usleep(1000*2000);

 munmap (fbp, finfo.smem_len); /*解除映射*/
 close(fp);
 return 0;
}


